/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

// Created on 09.12.2003 by RST.
// $Id: Lib.java,v 1.18 2005/12/18 22:10:12 cawe Exp $
using System;
using Globals = Suake2.UI.Globals;
using Com = Suake2.UI.qcommon.Com;
using FS = Suake2.UI.qcommon.FS;
//UPGRADE_TODO: The package 'java.nio' could not be found. If it was not included in the conversion, there may be compiler issues. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1262'"
using java.nio;
namespace Suake2.UI.util
{
	
	public class Lib
	{
		
		
		/// <summary>Converts a vector to a string. </summary>
		public static System.String vtos(float[] v)
		{
			//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
			return (int) v[0] + " " + (int) v[1] + " " + (int) v[2];
		}
		
		/// <summary>Converts a vector to a string. </summary>
		public static System.String vtofs(float[] v)
		{
			return v[0] + " " + v[1] + " " + v[2];
		}
		
		/// <summary>Converts a vector to a beatiful string. </summary>
		public static System.String vtofsbeaty(float[] v)
		{
			return Com.sprintf("%8.2f %8.2f %8.2f", new Vargs().add(v[0]).add(v[1]).add(v[2]));
		}
		
		/// <summary>Like in  libc. </summary>
		public static short rand()
		{
			return (short) Globals.rnd.Next(System.Int16.MaxValue + 1);
		}
		
		/// <summary>Like in libc. </summary>
		public static float crandom()
		{
			return ((float) Globals.rnd.NextDouble() - 0.5f) * 2.0f;
		}
		
		/// <summary>Like in libc. </summary>
		public static float random()
		{
			return (float) Globals.rnd.NextDouble();
		}
		
		/// <summary>Like in libc. </summary>
		public static float crand()
		{
			return ((float) Globals.rnd.NextDouble() - 0.5f) * 2.0f;
		}
		
		/// <summary>Like in libc. </summary>
		public static int strcmp(System.String in1, System.String in2)
		{
			return String.CompareOrdinal(in1, in2);
		}
		
		/// <summary>Like in libc. </summary>
		public static float atof(System.String in_Renamed)
		{
			float res = 0;
			
			try
			{
				res = System.Single.Parse(in_Renamed);
			}
			catch (System.Exception e)
			{
			}
			
			return res;
		}
		
		/// <summary>Like in quake2. </summary>
		public static int Q_stricmp(System.String in1, System.String in2)
		{
			return System.String.Compare(in1, in2, true);
		}
		
		/// <summary>Like in libc. </summary>
		public static int atoi(System.String in_Renamed)
		{
			try
			{
				return System.Int32.Parse(in_Renamed);
			}
			catch (System.Exception e)
			{
				try
				{
					//UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
					return (int) System.Double.Parse(in_Renamed);
				}
				catch (System.Exception e1)
				{
					return 0;
				}
			}
		}
		
		/// <summary>Converts a string to a vector. Needs improvement. </summary>
		public static float[] atov(System.String v)
		{
			float[] res = new float[]{0, 0, 0};
			System.String[] strres = v.split(" ");
			for (int n = 0; n < 3 && n < strres.Length; n++)
			{
				res[n] = atof(strres[n]);
			}
			return res;
		}
		
		/// <summary>Like in libc. </summary>
		public static int strlen(char[] in_Renamed)
		{
			for (int i = 0; i < in_Renamed.Length; i++)
				if (in_Renamed[i] == 0)
					return i;
			return in_Renamed.Length;
		}
		
		/// <summary>Like in libc. </summary>
		public static int strlen(sbyte[] in_Renamed)
		{
			for (int i = 0; i < in_Renamed.Length; i++)
				if (in_Renamed[i] == 0)
					return i;
			return in_Renamed.Length;
		}
		
		/// <summary>Converts memory to a memory dump string. </summary>
		public static System.String hexdumpfile(ByteBuffer bb, int len)
		{
			
			ByteBuffer bb1 = bb.slice();
			
			sbyte[] buf = new sbyte[len];
			
			bb1.get_Renamed(buf);
			
			return hexDump(buf, len, false);
		}
		
		/// <summary>Converts memory to a memory dump string. </summary>
		public static System.String hexDump(sbyte[] data1, int len, bool showAddress)
		{
			System.Text.StringBuilder result = new System.Text.StringBuilder();
			System.Text.StringBuilder charfield = new System.Text.StringBuilder();
			int i = 0;
			while (i < len)
			{
				if ((i & 0xf) == 0)
				{
					if (showAddress)
					{
						System.String address = System.Convert.ToString(i, 16);
						address = ("0000".Substring(0, (4 - address.Length) - (0)) + address).ToUpper();
						result.Append(address + ": ");
					}
				}
				int v = data1[i];
				
				result.Append(hex2(v));
				result.Append(" ");
				
				charfield.Append(readableChar(v));
				i++;
				
				// nach dem letzten, newline einfuegen
				if ((i & 0xf) == 0)
				{
					result.Append(charfield);
					result.Append("\n");
					charfield.Length = 0;
				}
				//	in der Mitte ein Luecke einfuegen ?
				else if ((i & 0xf) == 8)
				{
					result.Append(" ");
				}
			}
			return result.ToString();
		}
		
		/// <summary>Formats an hex byte. </summary>
		public static System.String hex2(int i)
		{
			System.String val = System.Convert.ToString(i & 0xff, 16);
			return ("00".Substring(0, (2 - val.Length) - (0)) + val).ToUpper();
		}
		
		/// <summary>Returns true if the char is alphanumeric. </summary>
		public static char readableChar(int i)
		{
			if ((i < 0x20) || (i > 0x7f))
				return '.';
			else
				return (char) i;
		}
		
		/// <summary>Prints a vector to the quake console. </summary>
		public static void  printv(System.String in_Renamed, float[] arr)
		{
			for (int n = 0; n < arr.Length; n++)
			{
				Com.Println(in_Renamed + "[" + n + "]: " + arr[n]);
			}
		}
		
		//UPGRADE_NOTE: Final was removed from the declaration of 'nullfiller '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
		internal static readonly sbyte[] nullfiller = new sbyte[8192];
		
		/// <summary>Like in libc. </summary>
		//UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'"
		public static void  fwriteString(System.String s, int len, System.IO.FileStream f)
		{
			if (s == null)
				return ;
			int diff = len - s.Length;
			if (diff > 0)
			{
				SupportClass.RandomAccessFileSupport.WriteRandomFile(stringToBytes(s), f);
				
				f.Write(SupportClass.ToByteArray(nullfiller), 0, diff);
			}
			else
				f.Write(SupportClass.ToByteArray(stringToBytes(s)), 0, len);
		}
		
		/// <summary>Like in libc </summary>
		//UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'"
		public static System.IO.FileStream fopen(System.String name, System.String mode)
		{
			try
			{
				return SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(name, mode);
			}
			catch (System.Exception e)
			{
				Com.DPrintf("Could not open file:" + name);
				return null;
			}
		}
		
		/// <summary>Like in libc </summary>
		//UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'"
		public static void  fclose(System.IO.FileStream f)
		{
			try
			{
				f.Close();
			}
			catch (System.Exception e)
			{
			}
		}
		
		/// <summary>Like in libc </summary>
		//UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'"
		public static System.String freadString(System.IO.FileStream f, int len)
		{
			sbyte[] buffer = new sbyte[len];
			FS.Read(buffer, len, f);
			
			return Lib.CtoJava(buffer);
		}
		
		/// <summary>Returns the right part of the string from the last occruence of c. </summary>
		public static System.String rightFrom(System.String in_Renamed, char c)
		{
			int pos = in_Renamed.LastIndexOf((System.Char) c);
			if (pos == - 1)
				return "";
			else if (pos < in_Renamed.Length)
				return in_Renamed.Substring(pos + 1, (in_Renamed.Length) - (pos + 1));
			return "";
		}
		
		/// <summary>Returns the left part of the string from the last occruence of c. </summary>
		public static System.String leftFrom(System.String in_Renamed, char c)
		{
			int pos = in_Renamed.LastIndexOf((System.Char) c);
			if (pos == - 1)
				return "";
			else if (pos < in_Renamed.Length)
				return in_Renamed.Substring(0, (pos) - (0));
			return "";
		}
		
		/// <summary>Renames a file. </summary>
		public static int rename(System.String oldn, System.String newn)
		{
			try
			{
				System.IO.FileInfo f1 = new System.IO.FileInfo(oldn);
				System.IO.FileInfo f2 = new System.IO.FileInfo(newn);
				//UPGRADE_TODO: Method 'java.io.File.renameTo' was converted to ' System.IO.FileInfo.MoveTo' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioFilerenameTo_javaioFile'"
				f1.MoveTo(f2.FullName);
				return 0;
			}
			catch (System.Exception e)
			{
				return 1;
			}
		}
		
		/// <summary>Converts an int to 4 bytes java representation. </summary>
		public static sbyte[] getIntBytes(int c)
		{
			sbyte[] b = new sbyte[4];
			b[0] = (sbyte) ((c & 0xff));
			b[1] = (sbyte) ((SupportClass.URShift(c, 8)) & 0xff);
			b[2] = (sbyte) ((SupportClass.URShift(c, 16)) & 0xff);
			b[3] = (sbyte) ((SupportClass.URShift(c, 24)) & 0xff);
			return b;
		}
		
		/// <summary>Converts an 4 bytes java int representation to an int. </summary>
		public static int getInt(sbyte[] b)
		{
			return (b[0] & 0xff) | ((b[1] & 0xff) << 8) | ((b[2] & 0xff) << 16) | ((b[3] & 0xff) << 24);
		}
		
		/// <summary>Duplicates a float array. </summary>
		public static float[] clone(float[] in_Renamed)
		{
			float[] out_Renamed = new float[in_Renamed.Length];
			
			if (in_Renamed.Length != 0)
				Array.Copy(in_Renamed, 0, out_Renamed, 0, in_Renamed.Length);
			
			return out_Renamed;
		}
		
		/// <summary> convert a java string to byte[] with 8bit latin 1
		/// 
		/// avoid String.getBytes() because it is using system specific character encoding.
		/// </summary>
		public static sbyte[] stringToBytes(System.String value_Renamed)
		{
			try
			{
				//UPGRADE_TODO: Method 'java.lang.String.getBytes' was converted to 'System.Text.Encoding.GetEncoding(string).GetBytes(string)' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javalangStringgetBytes_javalangString'"
				return SupportClass.ToSByteArray(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(value_Renamed));
			}
			catch (System.IO.IOException e)
			{
				// can't happen: Latin 1 is a standard encoding
				return null;
			}
		}
		
		/// <summary> convert a byte[] with 8bit latin 1 to java string
		/// 
		/// avoid new String(bytes) because it is using system specific character encoding.
		/// </summary>
		public static System.String bytesToString(sbyte[] value_Renamed)
		{
			try
			{
				//UPGRADE_TODO: The differences in the Format  of parameters for constructor 'java.lang.String.String'  may cause compilation errors.  "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1092'"
				return System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(SupportClass.ToByteArray(value_Renamed));
			}
			catch (System.IO.IOException e)
			{
				// can't happen: Latin 1 is a standard encoding
				return null;
			}
		}
		
		/// <summary>Helper method that savely handles the null termination of old C String data. </summary>
		public static System.String CtoJava(System.String old)
		{
			int index = old.IndexOf((System.Char) '\x0000');
			if (index == 0)
				return "";
			return (index > 0)?old.Substring(0, (index) - (0)):old;
		}
		
		/// <summary>Helper method that savely handles the null termination of old C String data. </summary>
		public static System.String CtoJava(sbyte[] old)
		{
			return CtoJava(old, 0, old.Length);
		}
		
		/// <summary>Helper method that savely handles the null termination of old C String data. </summary>
		public static System.String CtoJava(sbyte[] old, int offset, int maxLenght)
		{
			if (old.Length == 0 || old[0] == 0)
				return "";
			int i;
			for (i = offset; (i - offset) < maxLenght && old[i] != 0; i++)
				;
			return new System.String(SupportClass.ToCharArray(old), offset, i - offset);
		}
		
		
		/* java.nio.* Buffer util functions */
		
		public const int SIZEOF_FLOAT = 4;
		public const int SIZEOF_INT = 4;
		
		public static FloatBuffer newFloatBuffer(int numElements)
		{
			ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT);
			return bb.asFloatBuffer();
		}
		public static FloatBuffer newFloatBuffer(int numElements, ByteOrder order)
		{
			ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT, order);
			return bb.asFloatBuffer();
		}
		public static IntBuffer newIntBuffer(int numElements)
		{
			ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT);
			return bb.asIntBuffer();
		}
		public static IntBuffer newIntBuffer(int numElements, ByteOrder order)
		{
			ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT, order);
			return bb.asIntBuffer();
		}
		public static ByteBuffer newByteBuffer(int numElements)
		{
			ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
			bb.order(ByteOrder.nativeOrder());
			return bb;
		}
		public static ByteBuffer newByteBuffer(int numElements, ByteOrder order)
		{
			ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
			bb.order(order);
			return bb;
		}
	}
}